<template>
  <div class="upload-container">
    <div class="upload-content">
      <h2>上传视频</h2>
      
      <!-- 视频上传区域 -->
      <div
        class="upload-area"
        :class="{ 'is-dragover': isDragover }"
        @dragover.prevent="handleDragover"
        @dragleave.prevent="handleDragleave"
        @drop.prevent="handleDrop"
        v-if="!videoFile"
      >
        <el-upload
          class="upload-component"
          drag
          action="#" 
          :auto-upload="false"
          :show-file-list="false"
          accept="video/mp4,video/webm,video/ogg" 
          :on-change="handleFileChange"
          :disabled="isUploading"
        >
          <el-icon class="upload-icon"><Upload /></el-icon>
          <div class="upload-text">
            <h3>将视频拖到此处，或点击上传</h3>
            <p>支持 MP4、WebM、OGG 格式，文件大小不超过 500MB</p>
          </div>
        </el-upload>
      </div>
      
      <!-- 视频信息表单 -->
      <div class="video-form" v-if="videoFile">
        <div class="video-preview">
          <video
            ref="videoPreview"
            :src="videoPreviewUrl"
            controls
            class="preview-player"
            @loadedmetadata="handleVideoLoaded"
          ></video>

          <div class="video-file-info">
            <p>{{ videoFile.name }}</p>
            <p>{{ formatFileSize(videoFile.size) }}</p>
            <el-button text type="danger" @click="removeVideo" :disabled="isUploading">删除视频</el-button>
          </div>
        </div>

        <el-form
          ref="uploadFormRef"
          :model="uploadForm"
          :rules="uploadRules"
          label-position="top"
          :disabled="isUploading"
        >
          <el-form-item label="视频标题" prop="title">
            <el-input
              v-model="uploadForm.title"
              placeholder="请输入视频标题（2-100个字符）"
              maxlength="100"
              show-word-limit
            />
          </el-form-item>

          <el-form-item label="视频描述" prop="description">
            <el-input
              v-model="uploadForm.description"
              type="textarea"
              :rows="4"
              placeholder="请输入视频描述（最多5000个字符）"
              maxlength="5000"
              show-word-limit
            />
          </el-form-item>

          <el-form-item label="视频分类" prop="category">
            <el-select
              v-model="uploadForm.category"
              placeholder="请选择视频分类"
              style="width: 100%"
              filterable
              :loading="loadingCategories"
            >
              <el-option
                v-for="category in categories"
                :key="category.id || category._id"
                :label="category.name"
                :value="category.name" 
              />
            </el-select>
          </el-form-item>

          <el-form-item label="视频标签" prop="tags">
            <el-select
              v-model="uploadForm.tags"
              multiple
              filterable
              allow-create
              default-first-option
              placeholder="请输入标签，按回车确认（最多10个标签）"
              style="width: 100%"
              :max-collapse-tags="5" 
              :multiple-limit="10" 
            >
              <!-- 预设常用标签 -->
              <el-option label="教程" value="教程" />
              <el-option label="娱乐" value="娱乐" />
              <el-option label="音乐" value="音乐" />
              <el-option label="游戏" value="游戏" />
              <el-option label="科技" value="科技" />
              <el-option label="生活" value="生活" />
              <el-option label="电影" value="电影" />
              <el-option label="动漫" value="动漫" />
              <el-option label="体育" value="体育" />
              <el-option label="搞笑" value="搞笑" />
              <el-option label="旅游" value="旅游" />
              <el-option label="美食" value="美食" />
              <el-option label="宠物" value="宠物" />
              <el-option label="时尚" value="时尚" />
              <el-option label="健康" value="健康" />
            </el-select>
          </el-form-item>

          <el-form-item label="视频封面" prop="thumbnail">
            <div class="thumbnail-uploader">
              <el-upload
                class="thumbnail-upload"
                action="#" 
                :show-file-list="false"
                :auto-upload="false"
                accept="image/jpeg,image/png"
                :on-change="handleThumbnailChange"
                :limit="1"
                :on-exceed="handleThumbnailExceed"
                :disabled="isUploading"
              >
                <img v-if="thumbnailUrl" :src="thumbnailUrl" class="thumbnail" />
                <el-icon v-else class="thumbnail-uploader-icon"><Plus /></el-icon>
              </el-upload>
              <div class="thumbnail-actions">
                <el-button @click="captureThumbnail" :disabled="!videoPreviewUrl || isUploading">从视频截取</el-button>
                <div class="thumbnail-tips">
                  <p>建议尺寸：1280x720，格式：JPG、PNG</p>
                  <p>大小不超过 2MB</p>
                </div>
              </div>
            </div>
          </el-form-item>

          <el-form-item label="隐私设置" prop="privacy">
            <el-radio-group v-model="uploadForm.privacy">
              <el-radio value="public">公开</el-radio>
              <el-radio value="unlisted">不公开</el-radio>
              <el-radio value="private">私有</el-radio>
            </el-radio-group>
          </el-form-item>
        </el-form>

        <!-- 上传进度 -->
        <div class="upload-progress" v-if="isUploading">
          <el-progress
            :percentage="uploadProgress"
            :status="uploadStatus"
            :stroke-width="10"
            striped
            striped-flow
          />
          <p class="progress-text">{{ uploadStatusText }}</p>
        </div>

        <!-- 操作按钮 -->
        <div class="form-actions">
          <el-button @click="cancelUpload" :disabled="isUploading">取消</el-button>
          <el-button type="primary" @click="submitUpload" :loading="isUploading">
            {{ isUploading ? '上传中...' : '开始上传' }}
          </el-button>
        </div>
      </div>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onUnmounted, computed, onMounted, onBeforeUnmount } from 'vue'
import { useRouter } from 'vue-router'
import { ElMessage, ElMessageBox } from 'element-plus'
import { Upload, Plus } from '@element-plus/icons-vue'
import axios from '@/services/axios' // 使用自定义的 axios 实例
import { useStore } from 'vuex'

const router = useRouter()
const store = useStore()
const authToken = computed(() => store.getters['auth/token'])

// 表单引用
const uploadFormRef = ref(null)

// 拖拽状态
const isDragover = ref(false)

// 视频文件
const videoFile = ref(null) // 存储原始 File 对象
const videoPreviewUrl = ref('')
const videoPreview = ref(null) // video 元素引用
const videoDuration = ref(0)

// 封面文件
const thumbnailFile = ref(null) // 存储原始 File 对象
const thumbnailUrl = ref('')

// 状态轮询间隔ID
const statusPollInterval = ref(null);

// 上传状态
const isUploading = ref(false)
const uploadProgress = ref(0)
const uploadStatus = ref('') // success, exception
const uploadStatusText = ref('')
let cancelTokenSource = null // 用于取消上传

// 上传表单
const uploadForm = reactive({
  title: '',
  description: '',
  category: '',
  tags: [],
  privacy: 'public'
})

// 分类
const categories = ref([])
const loadingCategories = ref(false)

// 表单验证规则
const validateThumbnail = (rule, value, callback) => {
  if (!thumbnailFile.value) {
    callback(new Error('请上传或截取视频封面'));
  } else {
    callback();
  }
};

const uploadRules = {
  title: [
    { required: true, message: '请输入视频标题', trigger: 'blur' },
    { min: 2, max: 100, message: '长度在 2 到 100 个字符', trigger: 'blur' }
  ],
  description: [
    { max: 5000, message: '描述不能超过 5000 个字符', trigger: 'blur' }
  ],
  category: [
    { required: true, message: '请选择视频分类', trigger: 'change' }
  ],
  tags: [
      { type: 'array', max: 10, message: '最多添加 10 个标签', trigger: 'change' }
  ],
  thumbnail: [
      // 使用自定义验证器
      { required: true, validator: validateThumbnail, trigger: 'change' } 
  ]
}

// --- 文件处理 ---

const handleFileChange = (file) => {
  // 验证文件类型
  const allowedTypes = ['video/mp4', 'video/webm', 'video/ogg'];
  if (!allowedTypes.includes(file.raw.type)) {
    ElMessage.error('只支持 MP4、WebM、OGG 格式的视频文件！');
    return false;
  }

  // 验证文件大小（500MB）
  const maxSize = 500 * 1024 * 1024;
  if (file.raw.size > maxSize) {
    ElMessage.error('视频文件大小不能超过 500MB！');
    return false;
  }

  // 创建视频预览 URL
  if (videoPreviewUrl.value) {
    URL.revokeObjectURL(videoPreviewUrl.value);
  }
  videoPreviewUrl.value = URL.createObjectURL(file.raw);
  videoFile.value = file;

  // 自动填充标题（去除扩展名）
  if (!uploadForm.title) {
    uploadForm.title = file.name.replace(/\.[^\.]+$/, '');
  }

  // 重置上传状态
  uploadProgress.value = 0;
  uploadStatus.value = '';
  uploadStatusText.value = '';
  isUploading.value = false;

  return false; // 阻止自动上传
};

const handleDragover = (e) => {
  isDragover.value = true;
  e.dataTransfer.dropEffect = 'copy';
};

const handleDragleave = () => {
  isDragover.value = false;
};

const handleDrop = (e) => {
  isDragover.value = false;
  const files = e.dataTransfer.files;
  if (files.length > 0) {
    const file = files[0];
    handleFileChange({ raw: file, name: file.name });
  }
};

const removeVideo = () => {
  if (videoPreviewUrl.value) {
    URL.revokeObjectURL(videoPreviewUrl.value);
  }
  videoFile.value = null;
  videoPreviewUrl.value = '';
  videoDuration.value = 0;
  // 重置表单
  uploadForm.title = '';
  uploadForm.description = '';
  uploadFormRef.value?.resetFields();
};

const handleVideoLoaded = () => {
  if (videoPreview.value) {
    videoDuration.value = Math.round(videoPreview.value.duration)
  }
}

// --- 封面处理 ---

const handleThumbnailChange = (file) => {
    // 验证图片类型和大小
    const allowedTypes = ['image/jpeg', 'image/png'];
    const maxSize = 2 * 1024 * 1024; // 2MB

    if (!allowedTypes.includes(file.raw.type)) {
        ElMessage.error('封面图片只能是 JPG 或 PNG 格式!');
        return false;
    }
    if (file.raw.size > maxSize) {
        ElMessage.error('封面图片大小不能超过 2MB!');
        return false;
    }

    thumbnailFile.value = file.raw; // 存储原始 File 对象
    thumbnailUrl.value = URL.createObjectURL(file.raw);
    // 手动触发 thumbnail 字段的验证
    uploadFormRef.value?.validateField('thumbnail');
    return true; // 允许 Element Plus 处理预览
}

const handleThumbnailExceed = () => {
    ElMessage.warning('只能上传一张封面图片，请先移除现有封面');
}

const captureThumbnail = () => {
  if (!videoPreview.value) return

  const canvas = document.createElement('canvas')
  canvas.width = videoPreview.value.videoWidth
  canvas.height = videoPreview.value.videoHeight
  const ctx = canvas.getContext('2d')
  ctx.drawImage(videoPreview.value, 0, 0, canvas.width, canvas.height)

  canvas.toBlob((blob) => {
    thumbnailFile.value = new File([blob], 'thumbnail.png', { type: 'image/png' })
    // 清理之前的 Blob URL
    if (thumbnailUrl.value && thumbnailUrl.value.startsWith('blob:')) {
        URL.revokeObjectURL(thumbnailUrl.value);
    }
    thumbnailUrl.value = URL.createObjectURL(thumbnailFile.value)
    ElMessage.success('封面截取成功')
    // 手动触发 thumbnail 字段的验证
    uploadFormRef.value?.validateField('thumbnail');
  }, 'image/png')
}

// --- 上传逻辑 ---

// 轮询视频处理状态
const pollVideoStatus = async (videoId) => {
  const pollInterval = setInterval(async () => {
    try {
      const response = await axios.get(`/api/videos/${videoId}/status`);
      const { status, progress, error } = response.data;

      uploadProgress.value = progress;
      uploadStatus.value = status;

      if (error) {
        uploadStatusText.value = `处理失败: ${error}`;
        clearInterval(pollInterval);
        return;
      }

      switch (status) {
        case 'uploading':
          uploadStatusText.value = '正在上传视频...';
          break;
        case 'processing':
          uploadStatusText.value = `正在处理视频... ${progress}%`;
          break;
        case 'ready':
          uploadStatusText.value = '视频处理完成！';
          clearInterval(pollInterval);
          router.push(`/video/${videoId}`);
          break;
        case 'failed':
          uploadStatusText.value = '视频处理失败';
          clearInterval(pollInterval);
          ElMessage.error('视频处理失败，请重试');
          break;
      }
    } catch (error) {
      console.error('获取视频状态失败:', error);
      clearInterval(pollInterval);
      uploadStatusText.value = '获取处理状态失败';
    }
  }, 3000); // 每3秒轮询一次

  // 保存轮询间隔ID，以便在组件销毁时清除
  statusPollInterval.value = pollInterval;
};

// 在组件销毁时清除轮询
onBeforeUnmount(() => {
  if (statusPollInterval.value) {
    clearInterval(statusPollInterval.value);
  }
});

// 修改提交上传函数
const submitUpload = async () => {
  if (!uploadFormRef.value || !videoFile.value) return;

  await uploadFormRef.value.validate(async (valid) => {
    if (valid) {
      isUploading.value = true;
      uploadProgress.value = 0;
      uploadStatus.value = 'uploading';
      uploadStatusText.value = '准备上传...';

      const formData = new FormData();
      formData.append('video', videoFile.value.raw);
      formData.append('thumbnail', thumbnailFile.value);
      formData.append('title', uploadForm.title);
      formData.append('description', uploadForm.description);
      formData.append('category', uploadForm.category);
      formData.append('tags', JSON.stringify(uploadForm.tags));
      formData.append('privacy', uploadForm.privacy);

      try {
        const response = await axios.post('/api/videos/upload', formData, {
          headers: {
            'Content-Type': 'multipart/form-data'
          },
          timeout: 3600000 // 1小时超时
        });

        const { videoId } = response.data;
        // 开始轮询视频处理状态
        pollVideoStatus(videoId);

      } catch (error) {
        console.error('上传失败:', error);
        uploadStatus.value = 'failed';
        uploadStatusText.value = '上传失败';
        ElMessage.error(error.response?.data?.error || '上传失败，请稍后重试');
        isUploading.value = false;
      }
    } else {
      ElMessage.error('请检查表单信息是否完整');
      // 添加日志，检查具体哪个字段验证失败
      uploadFormRef.value.validate((_, invalidFields) => {
        console.error('表单验证失败，无效字段:', invalidFields);
        if (invalidFields && invalidFields.thumbnail) {
          console.error('封面验证失败详情:', invalidFields.thumbnail);
        }
      });
    }
  });
};

const cancelUpload = () => {
  if (isUploading.value && cancelTokenSource) {
    cancelTokenSource.cancel('用户取消上传')
  }
  // 重置所有状态
  removeVideo()
  thumbnailFile.value = null
  thumbnailUrl.value = ''
  uploadForm.title = ''
  uploadForm.description = ''
  uploadForm.category = ''
  uploadForm.tags = []
  uploadForm.privacy = 'public'
  isUploading.value = false
  uploadProgress.value = 0
  uploadStatus.value = ''
  uploadStatusText.value = ''
  uploadFormRef.value?.resetFields() // 重置表单验证状态
}

// --- 工具函数 ---

const formatFileSize = (size) => {
  if (size === 0) return '0 Bytes'
  const k = 1024
  const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB']
  const i = Math.floor(Math.log(size) / Math.log(k))
  return parseFloat((size / Math.pow(k, i)).toFixed(2)) + ' ' + sizes[i]
}

// --- 生命周期 ---

const fetchCategories = async () => {
    loadingCategories.value = true;
    try {
        // 由于普通用户可能无法访问管理员API，我们直接使用硬编码的分类数据
        // const response = await axios.get('/api/admin/categories'); 
        console.log('使用硬编码的分类数据');
        
        // 硬编码分类数据
        categories.value = [
            { id: '1', name: '音乐' },
            { id: '2', name: '游戏' },
            { id: '3', name: '教育' },
            { id: '4', name: '科技' },
            { id: '5', name: '生活' },
            { id: '6', name: '电影' },
            { id: '7', name: '动漫' },
            { id: '8', name: '体育' },
            { id: '9', name: '搞笑' },
            { id: '10', name: '其他' }
        ];
        console.log('处理后的分类数据:', categories.value);
    } catch (error) {
        console.error('获取分类列表失败:', error);
        ElMessage.error('获取分类列表失败');
    } finally {
        loadingCategories.value = false;
    }
};

// 工作区快捷键处理
const handleWorkspaceShortcut = (e) => {
  // 检查是否按下 @ 键
  if (e.key === '@' && !isUploading.value) {
    e.preventDefault();
    // 打开工作区选择器
    ElMessageBox.prompt('请输入工作区名称', '选择工作区', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      inputPlaceholder: '例如：我的视频、音乐等',
      inputValidator: (value) => {
        if (!value) {
          return '工作区名称不能为空';
        }
        return true;
      }
    }).then(({ value }) => {
      // 设置工作区
      uploadForm.category = value;
      ElMessage.success(`已选择工作区：${value}`);
    }).catch(() => {});
  }

  // 检查是否按下 # 键
  if (e.key === '#' && !isUploading.value) {
    e.preventDefault();
    // 打开标签选择器
    ElMessageBox.prompt('请输入标签', '添加标签', {
      confirmButtonText: '确定',
      cancelButtonText: '取消',
      inputPlaceholder: '输入标签，多个标签用逗号分隔',
      inputValidator: (value) => {
        if (!value) {
          return '标签不能为空';
        }
        const tags = value.split(',').map(tag => tag.trim());
        if (tags.length > 10) {
          return '最多添加10个标签';
        }
        return true;
      }
    }).then(({ value }) => {
      // 添加标签
      const newTags = value.split(',').map(tag => tag.trim());
      uploadForm.tags = [...new Set([...uploadForm.tags, ...newTags])];
      ElMessage.success('标签添加成功');
    }).catch(() => {});
  }
};

// 添加事件监听
onMounted(() => {
  fetchCategories();
  document.addEventListener('keydown', handleWorkspaceShortcut);
});

onUnmounted(() => {
  // 清理 Blob URL
  if (videoPreviewUrl.value && videoPreviewUrl.value.startsWith('blob:')) {
    URL.revokeObjectURL(videoPreviewUrl.value);
  }
  if (thumbnailUrl.value && thumbnailUrl.value.startsWith('blob:')) {
    URL.revokeObjectURL(thumbnailUrl.value);
  }
  // 如果仍在上传，取消上传
  if (isUploading.value && cancelTokenSource) {
    cancelTokenSource.cancel('组件卸载，取消上传');
  }
  // 移除事件监听
  document.removeEventListener('keydown', handleWorkspaceShortcut);
});
</script>

<style scoped>
.upload-container {
  padding: 40px 20px;
  max-width: 900px;
  margin: 0 auto;
  min-height: calc(100vh - 56px); /* 减去顶部导航栏高度 */
}

.upload-content {
  background-color: #fff;
  padding: 40px;
  border-radius: 8px;
  box-shadow: 0 2px 12px rgba(0, 0, 0, 0.06);
}

.upload-content h2 {
  text-align: center;
  font-size: 24px;
  margin-bottom: 30px;
  color: #303133;
}

/* 上传区域 */
.upload-area {
  border: 2px dashed #dcdfe6;
  border-radius: 6px;
  padding: 40px;
  text-align: center;
  cursor: pointer;
  transition: border-color 0.3s;
}

.upload-area:hover,
.upload-area.is-dragover {
  border-color: #409eff;
}

.upload-component {
  width: 100%;
}

.upload-component :deep(.el-upload-dragger) {
  border: none;
  padding: 0;
  background-color: transparent;
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  height: 200px; /* 增加高度 */
}

.upload-icon {
  font-size: 60px;
  color: #c0c4cc;
  margin-bottom: 16px;
}

.upload-text h3 {
  margin: 0 0 8px 0;
  font-size: 18px;
  color: #606266;
}

.upload-text p {
  font-size: 14px;
  color: #909399;
}

/* 视频表单 */
.video-form {
  margin-top: 30px;
}

.video-preview {
  display: flex;
  align-items: flex-start;
  margin-bottom: 30px;
  background-color: #f9f9f9;
  padding: 20px;
  border-radius: 6px;
}

.preview-player {
  width: 320px; /* 调整预览播放器大小 */
  height: 180px;
  margin-right: 20px;
  border-radius: 4px;
  background-color: #000;
}

.video-file-info p {
  margin: 0 0 8px 0;
  font-size: 14px;
}
.video-file-info p:first-child {
    font-weight: 500;
}

/* 封面上传 */
.thumbnail-uploader {
  display: flex;
  align-items: flex-start;
}

.thumbnail-upload {
  margin-right: 20px;
}

.thumbnail-upload :deep(.el-upload) {
  border: 1px dashed var(--el-border-color);
  border-radius: 6px;
  cursor: pointer;
  position: relative;
  overflow: hidden;
  transition: var(--el-transition-duration-fast);
  width: 178px;
  height: 101px; /* 16:9 */
  display: flex;
  align-items: center;
  justify-content: center;
}

.thumbnail-upload :deep(.el-upload:hover) {
  border-color: var(--el-color-primary);
}

.thumbnail {
  width: 100%;
  height: 100%;
  object-fit: cover;
}

.thumbnail-uploader-icon {
  font-size: 28px;
  color: #8c939d;
}

.thumbnail-actions {
    display: flex;
    flex-direction: column;
    gap: 10px;
}

.thumbnail-tips {
  font-size: 12px;
  color: #909399;
  line-height: 1.4;
}

/* 上传进度 */
.upload-progress {
  margin-top: 30px;
}

.progress-text {
  text-align: center;
  margin-top: 8px;
  font-size: 14px;
  color: #606266;
}

/* 操作按钮 */
.form-actions {
  margin-top: 30px;
  text-align: right;
}
</style>